package Gameplay.Weapon;

import java.util.ArrayList;

import ADTs.PointADT;
import Gameplay.Level;
import Gameplay.Player;
import Gameplay.Projectile.Projectile;
import Project.Main;
/**
 * This class contains all kinds of information of a weapon
 * such as weapon level, cool-down time, "friendly"(to decide
 * whether the weapon should make damage to player or enemy)
 * 
 * @author	Brian Wetherbee
 * 			Ryan McNamara
 * 			Zeng Yang
 *
 */
public class Weapon {
	//@ public invariant Main.playerInLevel == true;
	//@ public invariant weaponDamage > 0;
	
	private /*@ spec_public @*/ ArrayList<Integer> weaponLevel;
	private /*@ spec_public @*/ long cooldownTime; //milliseconds
	private /*@ spec_public @*/ double lastFiredTime;
	private boolean friendly;
	private String name;
	
	public Weapon(boolean friendly){
		this(null,friendly,"Awso-gun");
	}
	
	//Initialize all the weapon's details;
	public Weapon(ArrayList<Integer> weaponLevel, boolean friendly,String name){
		if (weaponLevel != null) {
			this.weaponLevel = (ArrayList<Integer>) weaponLevel.clone();
		}
		cooldownTime = 300;
		this.friendly = friendly;
		lastFiredTime = 0;
		this.name = name;
	}
	
	
	/*@ requires System.currentTimeMillis() - cooldownTime > lastFiredTime;
	  @ ensures lastFiredTime = System.currentTimeMillis();
	  @ ensures ((Level)Main.CurrentUI).state.getProjectileList().length() > old ((Level)Main.CurrentUI).state.getProjectileList().length() 
	  @*/
	public void fire(PointADT dest,PointADT loc){
		if (checkCooldown(true)) {
			((Level) Main.getCurrentUI()).addToState(new Projectile(dest, loc, friendly));
		}
	}
	
	//Returns if weapon is available to fire
	public boolean checkCooldown(boolean willFire){
		if(lastFiredTime < System.currentTimeMillis()-getCooldownTime()){
			//cooled down
			if(willFire){
				this.lastFiredTime = System.currentTimeMillis();
			}
			return true;
		}
		return false;
		
	}
	
	//@ requires aTime > 0;
	//@ ensures cooldownTime == aTime;
	public void setCooldownTime(long aTime){
		cooldownTime = aTime;
	}
	
	public long getCooldownTime(){
		return cooldownTime;
	}
	//@ ensures this.weaponLevel == weaponLevel;
	public void setWeaponLevel(/*@ spec_public @*/ ArrayList<Integer> weaponLevel) {
		this.weaponLevel = weaponLevel;
	}

	public /*@ spec_public @*/ ArrayList<Integer> getWeaponLevel() {
		return weaponLevel;
	}

	public String getName() {
		return name;
	}
}
